namespace TUnit.TestProject;

public enum Status
{
    Draft,
    Pending,
    Published,
    Archived,
    Deleted
}

// This is what the user might expect to work - a custom exclusion attribute
public class MatrixExclusionStatusAttribute : MatrixExclusionAttribute
{
    public MatrixExclusionStatusAttribute(Status status) : base(status)
    {
    }
}

public class MatrixExclusionBugTest
{
    [Test]
    [MatrixDataSource]
    [MatrixExclusionStatus(Status.Draft)]
    public async Task Should_Filter_By_Status(Status status)
    {
        // Should generate 4 tests (all statuses except Draft)
        // If this test runs with Status.Draft, the bug is NOT fixed
        if (status == Status.Draft)
        {
            throw new InvalidOperationException("Draft status should have been excluded but was not!");
        }
        await Task.CompletedTask;
    }

    [Test]
    [MatrixDataSource]
    [MatrixExclusion(Status.Draft)]  // This should work with the base attribute
    public async Task Should_Filter_By_Status_Base(Status status)
    {
        // Should generate 4 tests (all statuses except Draft)
        // If this test runs with Status.Draft, the bug is NOT fixed
        if (status == Status.Draft)
        {
            throw new InvalidOperationException("Draft status should have been excluded but was not!");
        }
        await Task.CompletedTask;
    }

    // Issue #3320: Test Matrix attribute with explicit enum values + MatrixExclusion
    [Test]
    [MatrixDataSource]
    [MatrixExclusion(Status.Draft)]
    public async Task Matrix_With_Explicit_Enums_Should_Respect_Exclusion(
        [Matrix(Status.Draft, Status.Pending, Status.Published)] Status status)
    {
        // Should generate 2 tests (Pending and Published only, Draft is excluded)
        await Assert.That(status).IsNotEqualTo(Status.Draft);
    }

    // Issue #3320: Test with multiple enum parameters and exclusion
    [Test]
    [MatrixDataSource]
    [MatrixExclusion(Status.Draft, Status.Pending)]
    public async Task Multiple_Enum_Matrix_With_Exclusion(
        [Matrix(Status.Draft, Status.Published)] Status status1,
        [Matrix(Status.Pending, Status.Archived)] Status status2)
    {
        // Should exclude (Draft, Pending) combination
        // Should generate 3 tests: (Draft,Archived), (Published,Pending), (Published,Archived)
        await Assert.That((status1, status2)).IsNotEqualTo((Status.Draft, Status.Pending));
    }

    // Issue #3320: Test with int cast exclusion (this was already working)
    [Test]
    [MatrixDataSource]
    [MatrixExclusion((int)Status.Draft)]
    public async Task Matrix_Enum_With_Int_Exclusion(
        [Matrix(Status.Draft, Status.Pending, Status.Published)] Status status)
    {
        // Should generate 2 tests (Pending and Published only)
        await Assert.That(status).IsNotEqualTo(Status.Draft);
    }

    // Issue #3320: Test mixing auto-generated and explicit Matrix enums
    [Test]
    [MatrixDataSource]
    [MatrixExclusion(Status.Draft, Status.Pending)]
    public async Task Mixed_Auto_And_Explicit_Matrix_Enums(
        Status autoGenerated,
        [Matrix(Status.Pending, Status.Published)] Status explicitMatrix)
    {
        // Should exclude (Draft, Pending) combination
        await Assert.That((autoGenerated, explicitMatrix)).IsNotEqualTo((Status.Draft, Status.Pending));
    }
}